﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using EmbeddedLanguage;

namespace EmbeddedLangTest
{
    class Program
    {
        #region TestForPrime1
        private static Expression<Func<int, bool>> TestForPrime1_expr = candidate =>
            candidate < 2
                ? false
                : 2.UpTo<bool>(candidate.Sqrt().ToInt(), new Range<bool>.RangeActionList
                {
                    rng => rng.If(
                        //if(
                        rng_ => candidate % rng_.Val == 0, 
                        //){ 
                        rng_ => rng_.Assign(out rng_.ReturnObj, false).Break(), 
                        //}else{
                        rng_ => rng_.Assign(out rng_.ReturnObj, true))
                        //}
                }).ReturnObj
        ;

        public static Func<int, bool> TestForPrime1;
        #endregion

        #region TestForPrime2
        private static Expression<Func<int, bool>> TestForPrime2_expr = candidate =>
            candidate < 2
                ? false
                : 
            Core<bool>.IntLoopSearch(2, candidate.Sqrt().ToInt() + 1, 
                //if
                i => candidate % i == 0, 
                //then
                i => false,
                //else
                () => true
            )
        ;

        public static Func<int, bool> TestForPrime2;
        #endregion

        #region TestForPrime3
        private static Expression<Func<int, bool>> TestForPrime3_expr = candidate =>
            new NumberInfo
            {
                Val = candidate
            }.Add(5)
            .IsPrime()
        ;

        public static Func<int, bool> TestForPrime3;
        #endregion

        #region Add 5
        private static Expression<Func<int, NumberInfo>> TestAdding_expr = candidate =>
            new NumberInfo
            {
                Val = candidate
            }.Add(5)
        ;

        public static Func<int, NumberInfo> TestAdding;
        #endregion

        private static Expression<Func<int, int>> Factorial_expr = candidate =>
            (new Seq<int, int>(candidate, 1)).DoRecursively(t => t.Item1 == 1, t => t.Assign(out t.Item2, t.Item1 * t.Item2).Assign(out t.Item1, t.Item1 - 1), null).Item2;

        private static Func<int, int> Factorial = Factorial_expr.Compile();

        #region Register Static Funcs
        private static Expression<Action<Program>> __Program = P => P
            .AssignStaticFunc_1x1(out TestForPrime1, TestForPrime1_expr)
            .AssignStaticFunc_1x1(out TestForPrime2, TestForPrime2_expr)
            .AssignStaticFunc_1x1(out TestForPrime3, TestForPrime3_expr)
            .AssignStaticFunc_1x1(out TestAdding, TestAdding_expr)
        ;

        static Program()
        {
            __Program.Compile().Invoke(null);
        }
        #endregion

        static void Main(string[] args)
        {
            
            var ns = AssemblyToJs.Generate(typeof(Program).Assembly);
            string s = ns.ToJS();
            ns.Save();
            var ns2 = AssemblyToJs.Generate(typeof(ObjectEx).Assembly);
            string t = ns2.ToJS();
            //Console.ReadKey();
        }
    }
}
